const express = require('express');
const path = require('path');
const os = require('os');
const fs = require('fs');
const multer = require('multer');
const archiver = require('archiver');

const app = express();
const PORT = 7749;

// 挂载静态文件夹 - 你可以修改这个路径指向你想要共享的文件夹
const STATIC_FOLDER = path.join(__dirname, 'public'); // 默认为当前目录下的public文件夹

// 设置静态文件夹 - 放在所有路由之前
app.use(express.static(STATIC_FOLDER));

// 设置static文件夹为静态资源
app.use('/static', express.static(path.join(__dirname, 'static')));

// 配置文件上传
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        // 从formData中获取path，如果没有则默认为根目录
        let uploadPath = '/';

        // 由于multer的限制，我们需要从req.body中获取path
        // 但是在处理文件时，req.body可能还没有完全解析
        // 所以我们先设置为根目录，稍后在路由中处理
        const fullPath = path.join(STATIC_FOLDER, uploadPath);

        // 确保目录存在
        if (!fs.existsSync(fullPath)) {
            fs.mkdirSync(fullPath, { recursive: true });
        }

        cb(null, fullPath);
    },
    filename: function (req, file, cb) {
        // 保持原始文件名，支持中文
        cb(null, Buffer.from(file.originalname, 'latin1').toString('utf8'));
    }
});

const upload = multer({
    storage: storage,
    limits: {
        fileSize: 500 * 1024 * 1024 // 限制文件大小为100MB
    }
});

// API 端点：获取文件列表
app.get('/api/files*', (req, res) => {
    const requestPath = req.path.replace('/api/files', '') || '/';
    const requestedPath = path.join(STATIC_FOLDER, requestPath);

    try {
        // 检查路径是否存在
        if (!fs.existsSync(requestedPath)) {
            return res.status(404).json({ error: '路径不存在' });
        }

        // 检查是否为目录
        const stats = fs.statSync(requestedPath);
        if (!stats.isDirectory()) {
            return res.status(400).json({ error: '不是目录' });
        }

        const files = fs.readdirSync(requestedPath);
        const fileList = files.map(file => {
            const filePath = path.join(requestedPath, file);
            const fileStats = fs.statSync(filePath);
            const isDirectory = fileStats.isDirectory();
            const relativePath = path.posix.join(requestPath, file);

            return {
                name: file,
                isDirectory,
                size: isDirectory ? 0 : fileStats.size,
                path: relativePath,
                modified: fileStats.mtime.toISOString()
            };
        }).sort((a, b) => {
            // 目录排在前面，然后按名称排序
            if (a.isDirectory && !b.isDirectory) return -1;
            if (!a.isDirectory && b.isDirectory) return 1;
            return a.name.localeCompare(b.name);
        });

        // 计算统计信息
        const stats_info = {
            fileCount: fileList.filter(f => !f.isDirectory).length,
            folderCount: fileList.filter(f => f.isDirectory).length,
            totalSize: fileList.filter(f => !f.isDirectory).reduce((sum, f) => sum + f.size, 0)
        };

        res.json({
            files: fileList,
            stats: stats_info,
            currentPath: requestPath
        });

    } catch (error) {
        console.error('读取目录失败:', error);
        res.status(500).json({ error: '读取目录失败' });
    }
});

// 根路径显示 index.html
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'index.html'));
});

// 文件上传端点
app.post('/api/upload', upload.array('files'), (req, res) => {
    try {
        if (!req.files || req.files.length === 0) {
            return res.status(400).json({ error: '没有文件被上传' });
        }

        const targetPath = req.body.path || '/';
        const targetDir = path.join(STATIC_FOLDER, targetPath);

        console.log('上传目标路径:', targetPath);
        console.log('目标目录:', targetDir);

        // 确保目标目录存在
        if (!fs.existsSync(targetDir)) {
            fs.mkdirSync(targetDir, { recursive: true });
        }

        const uploadedFiles = [];

        // 移动文件到正确的目录
        for (const file of req.files) {
            const originalName = Buffer.from(file.originalname, 'latin1').toString('utf8');
            const targetFilePath = path.join(targetDir, originalName);

            // 如果目标路径不是根目录，需要移动文件
            if (targetPath !== '/') {
                fs.renameSync(file.path, targetFilePath);
            }

            uploadedFiles.push({
                originalName: originalName,
                filename: originalName,
                size: file.size,
                path: path.posix.join(targetPath, originalName)
            });
        }

        res.json({
            success: true,
            message: `成功上传 ${uploadedFiles.length} 个文件到 ${targetPath}`,
            files: uploadedFiles
        });

    } catch (error) {
        console.error('文件上传失败:', error);
        res.status(500).json({ error: '文件上传失败' });
    }
});

// 创建文件夹端点
app.post('/api/mkdir', express.json(), (req, res) => {
    try {
        const { folderName, path: currentPath = '/' } = req.body;

        if (!folderName) {
            return res.status(400).json({ error: '文件夹名称不能为空' });
        }

        const fullPath = path.join(STATIC_FOLDER, currentPath, folderName);

        if (fs.existsSync(fullPath)) {
            return res.status(400).json({ error: '文件夹已存在' });
        }

        fs.mkdirSync(fullPath, { recursive: true });

        res.json({
            success: true,
            message: `文件夹 "${folderName}" 创建成功`
        });

    } catch (error) {
        console.error('创建文件夹失败:', error);
        res.status(500).json({ error: '创建文件夹失败' });
    }
});

// 删除文件/文件夹端点
app.delete('/api/delete', express.json(), (req, res) => {
    try {
        const { filePath } = req.body;

        if (!filePath) {
            return res.status(400).json({ error: '文件路径不能为空' });
        }

        const fullPath = path.join(STATIC_FOLDER, filePath);

        if (!fs.existsSync(fullPath)) {
            return res.status(404).json({ error: '文件或文件夹不存在' });
        }

        const stats = fs.statSync(fullPath);

        if (stats.isDirectory()) {
            fs.rmSync(fullPath, { recursive: true, force: true });
        } else {
            fs.unlinkSync(fullPath);
        }

        res.json({
            success: true,
            message: `${stats.isDirectory() ? '文件夹' : '文件'}删除成功`
        });

    } catch (error) {
        console.error('删除失败:', error);
        res.status(500).json({ error: '删除失败' });
    }
});

// 下载文件或文件夹端点
app.get('/downloader', async (req, res) => {
    try {
        const requestPath = req.query.filepath;
        if (!requestPath) {
            return res.status(400).json({ error: '缺少 filepath 参数' });
        }

        const staticRoot = path.resolve(STATIC_FOLDER);
        // 规范化并拼接路径（始终当作以 "/" 开头的相对路径）
        const normalizedPosix = path.posix.normalize(requestPath);
        const ensuredLeadingSlash = normalizedPosix.startsWith('/') ? normalizedPosix : ('/' + normalizedPosix);
        const fullPath = path.join(STATIC_FOLDER, ensuredLeadingSlash);
        const resolvedPath = path.resolve(fullPath);

        // 目录越权检查
        if (resolvedPath !== staticRoot && !resolvedPath.startsWith(staticRoot + path.sep)) {
            return res.status(403).json({ error: '非法路径' });
        }

        if (!fs.existsSync(resolvedPath)) {
            return res.status(404).json({ error: '文件或文件夹不存在' });
        }

        const stat = fs.statSync(resolvedPath);

        // 设置 Content-Disposition
        function buildContentDisposition(filename) {
            const safeFallback = filename.replace(/[^\x20-\x7E]/g, '_');
            const encoded = encodeURIComponent(filename).replace(/['()]/g, escape).replace(/\*/g, '%2A');
            return `attachment; filename="${safeFallback}"; filename*=UTF-8''${encoded}`;
        }

        if (stat.isFile()) {
            const fileName = path.basename(resolvedPath);
            res.setHeader('Content-Disposition', buildContentDisposition(fileName));
            return res.download(resolvedPath, fileName, (err) => {
                if (err) {
                    if (!res.headersSent) {
                        res.status(500).json({ error: '文件下载失败' });
                    }
                }
            });
        }

        // 文件夹：打包为 ZIP 流式输出
        const folderName = path.basename(resolvedPath) || 'folder';
        res.setHeader('Content-Type', 'application/zip');
        res.setHeader('Content-Disposition', buildContentDisposition(`${folderName}.zip`));

        const archive = archiver('zip', { zlib: { level: 9 } });
        archive.on('error', (err) => {
            console.error('压缩失败:', err);
            if (!res.headersSent) {
                res.status(500).end('压缩失败');
            } else {
                res.end();
            }
        });

        // 将目录内容放入 ZIP，根目录名为文件夹名
        archive.directory(resolvedPath, folderName);
        archive.pipe(res);
        archive.finalize();
    } catch (error) {
        console.error('下载失败:', error);
        if (!res.headersSent) {
            res.status(500).json({ error: '下载失败' });
        }
    }
});

// 获取本机IP地址
function getLocalIPAddress() {
    const interfaces = os.networkInterfaces();
    for (const name of Object.keys(interfaces)) {
        for (const interface of interfaces[name]) {
            if (interface.family === 'IPv4' && !interface.internal) {
                return interface.address;
            }
        }
    }
    return 'localhost';
}

// 启动服务器
app.listen(PORT, '0.0.0.0', () => {
    const localIP = getLocalIPAddress();
    console.log(`\n📁 静态文件服务器已启动!`);
    console.log(`🌐 局域网访问地址: http://${localIP}:${PORT}`);
    console.log(`🏠 本地访问地址: http://localhost:${PORT}`);
    console.log(`📂 共享目录: ${STATIC_FOLDER}`);
    console.log(`\n💡 提示: 将文件放入共享目录，然后通过浏览器访问 http://${localIP}:${PORT}/文件名`);
    console.log(`⚠️  确保防火墙允许端口 ${PORT} 的连接\n`);
});

// 优雅关闭
process.on('SIGINT', () => {
    console.log('\n👋 服务器已关闭');
    process.exit(0);
});
